package com.zx.cloud.controller;

import java.math.BigDecimal;

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.lianpay.api.util.TraderRSAUtil;
import com.zx.cloud.ApiVersion;
import com.zx.cloud.common.filter.IgnoreAuth;
import com.zx.cloud.domain.BusinessNoticeBean;
import com.zx.cloud.domain.LoanOrder;
import com.zx.cloud.domain.NotifyResponseBean;
import com.zx.cloud.domain.RepayOrder;
import com.zx.cloud.domain.enums.PaymentStatusEnum;
import com.zx.cloud.model.response.ObjectDataResponse;
import com.zx.cloud.model.response.Response;
import com.zx.cloud.service.LoanOrderService;
import com.zx.cloud.service.RepayOrderService;
import com.zx.cloud.util.PaymentConstant;
import com.zx.cloud.util.SignUtil;

import io.swagger.annotations.ApiOperation;

/**
 * @Description:
 *
 * @author       Yan Weiwei
 * @Create Time: 2017年11月17日上午10:46:39
 */

@RestController
@RequestMapping(value = ApiVersion.PROVIDER_V1_PREFIX+"/payfor")
public class PayForAnotherController {
	
	private static final Logger logger=Logger.getLogger(PayForAnotherController.class);
	@Autowired
	private LoanOrderService  loanOrderService;
	@Autowired
	private RepayOrderService  repayOrderService;

	@IgnoreAuth
	@ApiOperation(value = "异步获取付款申请时回调方法" , notes = "异步获取付款申请时回调方法")
	@RequestMapping(value = "/receiveNotify", method = RequestMethod.POST)
	@ResponseBody
	public Response receiveNotify(@RequestBody BusinessNoticeBean businessNoticeBean) {
		NotifyResponseBean responseBean =null;
		try {
			logger.info("============================receiveNotify======================");
			logger.info("==========================================================");
			logger.info("==============notify request:" + businessNoticeBean.toString()+"==============");
			responseBean = new NotifyResponseBean();
			boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
					SignUtil.genSignData(new JSONObject(businessNoticeBean)),
					businessNoticeBean.getSign());
			
			if (!signCheck) {
				logger.error("返回结果验签异常,可能数据被篡改");
				responseBean.setRet_code("9999");
				responseBean.setRet_msg("未知异常");
			}
			logger.info("==============businessNoticeBean.getResult_pay():" + businessNoticeBean.getResult_pay()+"==============");
			logger.info("==============businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue()):" + businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())+"==============");
			if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())) {
				// TODO 商户更新订单为成功，处理自己的业务逻辑
				logger.info("========正常付款申请时回调======放款回调开始==============");
				LoanOrder loanOrder=new LoanOrder();
				loanOrder.setOrderNo(businessNoticeBean.getNo_order());
				loanOrder.setSerialNumber(businessNoticeBean.getOid_paybill());
				
				loanOrderService.doLendingCallBack(loanOrder);
				
				responseBean.setRet_code("0000");
				responseBean.setRet_msg("交易成功");
				logger.info("========正常付款申请时回调======放款回调结束==============");
			} else if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_FAILURE.getValue())) {
				// TODO 商户更新订单为失败，处理自己的业务逻辑
				logger.info("==============商户更新订单为失败，处理自己的业务逻辑==============");
			} else {
				// TODO 返回订单为退款状态 ，商户可以更新订单为失败或者退款
				// 退款这种情况是极小概率情况下才会发生的，个别银行处理机制是先扣款后再打款给用户时，
				// 才检验卡号姓名信息的有效性，当卡号姓名信息有误发生退款，实际上钱没打款到商户。
				// 这种情况商户代码上也可不做考虑，如发生用户投诉未收到钱，可直接联系连连客服，连连会跟银行核对
				// 退款情况，异步通知会通知两次，先通知成功，后通知退款（极小概率情况下才会发生的）
				logger.info("==============返回订单为退款状态 ，商户可以更新订单为失败或者退款==============");
			}
		
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ObjectDataResponse<NotifyResponseBean>(responseBean);
	}
	
	@IgnoreAuth
	@ApiOperation(value = "异步获取付款时回调方法" , notes = "异步获取付款时回调方法")
	@RequestMapping(value = "/receiveConfirmNotify", method = RequestMethod.POST)
	@ResponseBody
	public Response receiveConfirmNotify(@RequestBody BusinessNoticeBean businessNoticeBean) throws Exception{
		logger.info("============================receiveConfirmNotify======================");
		logger.info("==========================================================");
		logger.info("==============notify request:" + businessNoticeBean.toString()+"==============");
		NotifyResponseBean responseBean = new NotifyResponseBean();
		boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
				SignUtil.genSignData(new JSONObject(businessNoticeBean)),
				businessNoticeBean.getSign());
		
		if (!signCheck) {
			logger.error("返回结果验签异常,可能数据被篡改");
			responseBean.setRet_code("9999");
			responseBean.setRet_msg("未知异常");
		}
		logger.info("==============businessNoticeBean.getResult_pay():" + businessNoticeBean.getResult_pay()+"==============");
		logger.info("==============businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue()):" + businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())+"==============");
		if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())) {
			logger.info("==============人工确认付款=放款回调开始==============");
			LoanOrder loanOrder=new LoanOrder();
			loanOrder.setOrderNo(businessNoticeBean.getNo_order());
			loanOrder.setSerialNumber(businessNoticeBean.getOid_paybill());
			loanOrderService.doLendingCallBack(loanOrder);
			
			responseBean.setRet_code("0000");
			responseBean.setRet_msg("交易成功");
			logger.info("==============人工确认付款=放款回调结束==============");
			// TODO 商户更新订单为成功，处理自己的业务逻辑
		} else if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_FAILURE.getValue())) {
			// TODO 商户更新订单为失败，处理自己的业务逻辑
			logger.info("==============商户更新订单为失败，处理自己的业务逻辑==============");
		} else {
			// TODO 返回订单为退款状态 ，商户可以更新订单为失败或者退款
			// 退款这种情况是极小概率情况下才会发生的，个别银行处理机制是先扣款后再打款给用户时，
			// 才检验卡号姓名信息的有效性，当卡号姓名信息有误发生退款，实际上钱没打款到商户。
			// 这种情况商户代码上也可不做考虑，如发生用户投诉未收到钱，可直接联系连连客服，连连会跟银行核对
			// 退款情况，异步通知会通知两次，先通知成功，后通知退款（极小概率情况下才会发生的）
			logger.info("==============返回订单为退款状态 ，商户可以更新订单为失败或者退款==============");
		}
		
		
		return new ObjectDataResponse<NotifyResponseBean>(responseBean);
	}
	
	@IgnoreAuth
	@ApiOperation(value = "异步获取银行卡还款回调方法" , notes = "异步获取银行卡还款回调方法")
	@RequestMapping(value = "/receiveRepaymentNotify", method = RequestMethod.POST)
	@ResponseBody
	public Response receiveRepaymentNotify(@RequestBody BusinessNoticeBean businessNoticeBean) throws Exception{
		logger.info("*******************************还款回调开始****************************************");
		logger.info("*******************************notify request:" + businessNoticeBean.toString()+"****************************************");
		NotifyResponseBean responseBean = new NotifyResponseBean();
		boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
				SignUtil.genSignData(new JSONObject(businessNoticeBean)),
				businessNoticeBean.getSign());
		
		if (!signCheck) {
			logger.error("*******************************返回结果验签异常,可能数据被篡改*******************************");
			responseBean.setRet_code("9999");
			responseBean.setRet_msg("未知异常");
		}
		
		if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())) {
			// TODO 商户更新订单为成功，处理自己的业务逻辑
			logger.error("*******************************商户更新订单为成功，处理自己的业务逻辑*******************************");
			/**还款成功*/
			RepayOrder  repayOrder=new  RepayOrder();
			repayOrder.setTradeNumber(businessNoticeBean.getNo_order());
			BigDecimal actualAmont=new BigDecimal(businessNoticeBean.getMoney_order());
			repayOrder.setActualAmount(actualAmont);
			repayOrder.setSerialNumber(businessNoticeBean.getOid_paybill());
			repayOrderService.repaymentCallBack(repayOrder);
			
			
			
		} else if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_FAILURE.getValue())) {
			// TODO 商户更新订单为失败，处理自己的业务逻辑
			logger.error("*******************************商户更新订单为失败，处理自己的业务逻辑*******************************");
		} else {
			// TODO 返回订单为退款状态 ，商户可以更新订单为失败或者退款
			// 退款这种情况是极小概率情况下才会发生的，个别银行处理机制是先扣款后再打款给用户时，
			// 才检验卡号姓名信息的有效性，当卡号姓名信息有误发生退款，实际上钱没打款到商户。
			// 这种情况商户代码上也可不做考虑，如发生用户投诉未收到钱，可直接联系连连客服，连连会跟银行核对
			// 退款情况，异步通知会通知两次，先通知成功，后通知退款（极小概率情况下才会发生的）
			logger.error("*******************************TODO 返回订单为退款状态 ，商户可以更新订单为失败或者退款*******************************");
		}
		responseBean.setRet_code("0000");
		responseBean.setRet_msg("交易成功");
		
		return new ObjectDataResponse<NotifyResponseBean>(responseBean);
	}
	
}
